#pragma once

#ifndef __GLOBAL_H__
#define __GLOBAL_H__

#include <mutex>
#include <opencv2/opencv.hpp>
#include "cache.hpp"
// #include "lru_cache_policy.hpp"
#include "fifo_cache_policy.hpp"
#include "spdlog/async.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include <SQLiteCpp/SQLiteCpp.h>
#include <SQLiteCpp/VariadicBind.h>

#include "sample_comm_nnie.h"
#include "types.h"

//定义运行全局变量
int g_running = 0;

// /* NNIE para*/
SAMPLE_SVP_NNIE_MODEL_S                 s_stYoloModel;
SAMPLE_SVP_NNIE_PARAM_S                 s_stYoloNnieParam;
SAMPLE_SVP_NNIE_YOLOV3_SOFTWARE_PARAM_S s_stYolov3SoftwareParam;
SAMPLE_SVP_NNIE_CFG_S                   stNnieCfg_SDC;

std::shared_ptr<spdlog::logger> logger;

// 全局变量初始化
static void ResetGlobalVars(void)
{
    memset_s(&s_stYoloModel, sizeof(s_stYoloModel), 0, sizeof(s_stYoloModel));
    memset_s(&s_stYoloNnieParam, sizeof(s_stYoloNnieParam), 0, sizeof(s_stYoloNnieParam));
    memset_s(&s_stYolov3SoftwareParam, sizeof(s_stYolov3SoftwareParam), 0, sizeof(s_stYolov3SoftwareParam));
    memset_s(&stNnieCfg_SDC, sizeof(stNnieCfg_SDC), 0, sizeof(stNnieCfg_SDC));

    auto max_size = 1048576 * 5;
    auto max_files = 2;
    if (LOG_DEBUG_LEVEL) {
        max_files = 10;
    }

    auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(LOG_PATH, max_size, max_files, true);
    if (LOG_DEBUG_LEVEL) {
        file_sink->set_level(spdlog::level::debug);
    } else {
        file_sink->set_level(spdlog::level::info);
    }
    file_sink->set_pattern("%5P:%-6t %Y-%m-%d %H:%M:%S.%e [%^%l%$] [%@] [%!] %v");    

    auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
    console_sink->set_level(spdlog::level::debug);
    console_sink->set_pattern("%+");

    std::vector<spdlog::sink_ptr> sinks;
    sinks.push_back(file_sink);
    sinks.push_back(console_sink);
    logger = std::make_shared<spdlog::logger>("multi-sink", begin(sinks), end(sinks));
    if (LOG_DEBUG_LEVEL) {
        logger->set_level(spdlog::level::debug);
    } else {
        logger->set_level(spdlog::level::info);
    }    
}

std::mutex gc_app_config_mutex;
GC_APP_CONFIG gc_app_config;
// TODO configable
caches::fixed_sized_cache<std::string, cv::Mat, caches::FIFOCachePolicy> IMG_CACHE(gc_app_config.base_config.alg_config.img_cache_size);

std::string app_start_time;

SQLite::Database    gc_db(DB_PATH, SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);

// FIXME 这里没有支持多预置位情况
std::mutex last_track_data_mutex;
GCTrackData last_track_data;
float m_mapRatio = 1.0f;

std::map<std::string, int> PLATE_COLOR_MAP = {
    { "蓝牌", 1 },
    { "黄牌", 2 },
    { "黑牌", 3 },
    { "白牌", 4 },
    { "绿牌", 5 },
    { "黄绿", 6 },
    { "", 1 }, // 默认蓝牌
};

// std::vector<std::string> PLATE_CHAR_LIST = {"#","京","沪","津","渝","冀","晋","蒙","辽","吉","黑","苏","浙","皖", \
//     "闽","赣","鲁","豫","鄂","湘","粤","桂","琼","川","贵","云","藏","陕","甘","青","宁","新","学","警","港","澳","挂","使","领","民","航","深", \
//     "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z"};

std::vector<std::string> PLATE_CHAR_LIST = {"#","京","沪","津","渝","冀","晋","蒙","辽","吉","黑","苏","浙","皖", \
    "闽","赣","鲁","豫","鄂","湘","粤","桂","琼","川","贵","云","藏","陕","甘","青","宁","新","学","警","港","澳","挂","使","领","民","航","危", \
    "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z","险","品","西峡","电动备案","临"};

std::vector<std::string> PLATE_CHINESE_CHAR_LIST = {"京","沪","津","渝","冀","晋","蒙","辽","吉","黑","苏","浙","皖", \
    "闽","赣","鲁","豫","鄂","湘","粤","桂","琼","川","贵","云","藏","陕","甘","青","宁","新","学","警","港","澳","挂","使","领","民","航","危", \
    "险","品","西峡","电动备案","临"};

#endif